package com.wh.wisdomsite.xbox.utils.random;

import com.wh.wisdomsite.xbox.utils.StringUtils;
import com.wh.wisdomsite.xbox.utils.date.DateTool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.Date;
import java.util.Random;


/**
 * 随机数工具类
 * @Package com.wh.wisdomsite.xbox.utils.random
 * @author 谢泽鹏
 * @date 2014年10月8日 下午4:02:14
 * @Copyright 个人版权所有
 * @Company 贵州万华科技有限公司Copyright (c) 2014
 * @version V1.0
 */
public class RandomTool {

    private static final Log logger = LogFactory.getLog(RandomTool.class);

    //大写
    private static int uppercase = 65;

    //小写
    private static int lowercase  = 97;

    //随机码生成范围(0-9)
    public static final String NUMBER = "0123456789";

    //随机码生成范围(A-Z, a-z)
    public static final String LETTER_ALL = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //随机码生成范围(0-9, a-z, A-Z)
    public static final String NUMBER_LETTER_ALL = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //随机码生成范围(0-9, a-z, A-Z, -_!@#$%^&*)
    public static final String NUMBER_LETTER_SYMBOL_ALL = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_!@#$%^&*";

    //随机码生成范围(A-Z)
    public static final String LETTER_UPPER_CASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //随机码生成范围(a-z)
    public static final String LETTER_LOWER_CASE = "abcdefghijklmnopqrstuvwxyz";

    //随机码生成范围(0-9,A-Z)
    public static final String NUMBER_LETTER_UPPER_CASE = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    //随机码生成范围(0-9,a-z)
    public static final String NUMBER_LETTER_LOWER_CASE = "0123456789abcdefghijklmnopqrstuvwxyz";


    //随机码生成数组范围(0-9, A-Z)
    public static final String[] NUMBERLETTER_ALL_ARRAY = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };


    //随机码生成数组范围(0-9)
    public static final String[] NUMBER_ARRAY = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

    /**
     * 获取制定长度的随机码，范围(0-9, a-z, A-Z, -_!@#$%^&*)
     * @param length
     * @return
     */
    public static String getNumberLetterSymbol(int length) { return getRandom(NUMBER_LETTER_SYMBOL_ALL, length);}

    /**
     * 获取指定长度随机码,范围(0-9)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getNumber(int length) {
        return getRandom(NUMBER, length);
    }

    /**
     * 获取指定长度随机码,范围(a-z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getLetterLowerCase(int length) {
        return getRandom(LETTER_LOWER_CASE, length);
    }

    /**
     * 获取指定长度随机码,范围(A-Z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getLetterUpperCase(int length) {
        return getRandom(LETTER_UPPER_CASE, length);
    }


    /**
     * 获取指定长度随机码,范围(A-Z, a-z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getLetterAll(int length) {
        return getRandom(LETTER_ALL, length);
    }

    /**
     * 获取指定长度随机码,范围(0-9,A-Z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getNumberLetterUpperCase(int length){
        return getRandom(NUMBER_LETTER_UPPER_CASE, length);
    }

    /**
     * 获取指定长度随机码,范围(0-9,a-z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getNumberLetterLowerCase(int length){
        return getRandom(NUMBER_LETTER_LOWER_CASE, length);
    }


    /**
     * 获取指定长度随机码,范围(0-9, A-Z, a-z)
     * @param  length 随机码长度
     * @return String 随机码
     */
    public static String getNumberLetterAll(int length) {
        return getRandom(NUMBER_LETTER_ALL, length);
    }


    /**
     * 生成随机码入口
     * @param source 随机码范围
     * @param length 随机码长度
     * @return String
     */
    public static String getRandom(String source, int length) {
        return StringUtils.isEmpty(source) ? null : getRandom(source.toCharArray(), length);
    }


    /**
     * 执行生成随机码
     * @param sourceChar 字符集
     * @param length	 长度
     * @return String    生成字符
     */
    public static String getRandom(char[] sourceChar, int length) {
        if (sourceChar == null || sourceChar.length == 0 || length < 0) {
            return null;
        }
        StringBuilder str = new StringBuilder(length);
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            str.append(sourceChar[random.nextInt(sourceChar.length)]);
        }
        return str.toString();
    }




    /**
     * 获取系统时间(格式：yyyyMMddHHmmssSSS)17位 + number = 共xx位
     * @param range
     *
     * 1：范围(0-9)
     * 2：范围(a-z)
     * 3：范围(A-Z)
     * 4：范围(A-Z,a-z)
     * 5：范围(A-Z,a-z)
     * 6：范围(0-9,A-Z)
     * 7：范围(0-9,a-z)
     * 8：范围(0-9, A-Z, a-z)
     *
     * @return String 返回时间
     */
    public static String getStringTimeFullRandom(int range, int number){
        String result = null;
        switch (range){
            //范围(0-9)
            case 1:
                result = DateTool.getStringTimeFull() + getNumber(number);
                break;
            //范围(a-z)
            case 2:
                result = DateTool.getStringTimeFull() + getLetterLowerCase(number);
                break;
            //范围(A-Z)
            case 3:
                result = DateTool.getStringTimeFull() + getLetterUpperCase(number);
                break;
            case 4:
            //范围(A-Z)
                result = DateTool.getStringTimeFull() + getNumberLetterAll(number);
                break;
            //范围(A-Z, a-z)
            case 5:
                result = DateTool.getStringTimeFull() + getLetterAll(number);
                break;
            //范围(0-9,A-Z)
            case 6:
                result = DateTool.getStringTimeFull() + getNumberLetterUpperCase(number);
                break;
            //范围(0-9,a-z)
            case 7:
                result = DateTool.getStringTimeFull() + getNumberLetterLowerCase(number);
                break;
            //范围(0-9, A-Z, a-z)
            case 8:
                result = DateTool.getStringTimeFull() + getNumberLetterAll(number);
                break;
            //自定义
            default:
                break;
        }
            logger.info("getStringTimeFullRandom->>code：" + result);
            return result;
    }




    /**
     * 获取系统时间(格式：yyyyMMddHHmmss)14位 + number = 共xx位
     * @param range
     *
     * 1：范围(0-9)
     * 2：范围(a-z)
     * 3：范围(A-Z)
     * 4：范围(A-Z,a-z)
     * 5：范围(A-Z,a-z)
     * 6：范围(0-9,A-Z)
     * 7：范围(0-9,a-z)
     * 8：范围(0-9, A-Z, a-z)
     *
     * @return String 返回时间
     */
    public static String getStringTimeRandom(int range, int number){
        String result = null;
        switch (range){
            //范围(0-9)
            case 1:
                result = DateTool.getStringTime() + getNumber(number);
                break;
            //范围(a-z)
            case 2:
                result = DateTool.getStringTime() + getLetterLowerCase(number);
                break;
            //范围(A-Z)
            case 3:
                result = DateTool.getStringTime() + getLetterUpperCase(number);
                break;
            case 4:
                //范围(A-Z)
                result = DateTool.getStringTime() + getNumberLetterAll(number);
                break;
            //范围(A-Z, a-z)
            case 5:
                result = DateTool.getStringTime() + getLetterAll(number);
                break;
            //范围(0-9,A-Z)
            case 6:
                result = DateTool.getStringTime() + getNumberLetterUpperCase(number);
                break;
            //范围(0-9,a-z)
            case 7:
                result = DateTool.getStringTime() + getNumberLetterLowerCase(number);
                break;
            //范围(0-9, A-Z, a-z)
            case 8:
                result = DateTool.getStringTime() + getNumberLetterAll(number);
                break;
            //自定义
            default:
                break;
        }
            logger.info("getStringTimeRandom->>code：" + result);
            return result;
    }


    /**
     * 招商贷交易流水号
     * @return
     */
    public static String GetZsdSerialNo(){
        //14位时间/10 = 12时间 + 7位随机数
        String nowTime = ((new Date().getTime() / 10) + new Random().nextInt(9999999)) + "";
        //两位随机数
        String lastNo = ((int)(Math.random() * 90 + 10)) + "";
        logger.info("getStringTimeRandom->>code：" + "YB" + nowTime + lastNo);
        return "YB" + nowTime + lastNo;
    }





    /**
     *
     * 生成不含有大写元音字母组合随机字符
     * @param length : 生成随机字符的长度
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterCharNotContainVowelsToUppercase(int length) {
        Random random = new Random();
        double randMunber;
        double randSetup;
        char randCharater;
        String str = "";
        for (int i = 0; i < length; i++) {
            randMunber = random.nextDouble();
            //运算后
            randSetup = randMunber * 26 + uppercase;
            //转换成字母
            randCharater = (char) randSetup;
            switch (randCharater) {
                case 'A':
                case 'E':
                case 'I':
                case 'O':
                case 'U':
                    i--;
                    //System.out.println("字母为元音字母");
                    continue;
                default:
                    //System.out.println("字母为辅音字母");
                    str += randCharater;
            }
        }
        return str;
    }

    /**
     *
     * 生成不含有小写元音字母组合随机字符
     * @param length : 生成随机字符的长度
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterCharNotContainVowelsToLower(int length) {
        Random random = new Random();
        double randMunber;
        double randSetup;
        char randCharater;
        String str = "";
        for (int i = 0; i < length; i++) {
            randMunber = random.nextDouble();
            //运算后
            randSetup = randMunber * 26 + lowercase;
            //转换成字母
            randCharater = (char) randSetup;
            switch (randCharater) {
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u':
                    i--;
                    //System.out.println("字母为元音字母");
                    continue;
                default:
                    //System.out.println("字母为辅音字母");
                    str += randCharater;
            }
        }
        return str;
    }
    /**
     *
     * 生成大写字母组合随机字符
     * @param length
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterCharToUppercase(int length) {
        Random random = new Random();
        double randMunber;
        double randSetup;
        char randCharater;
        String str = "";
        for (int i = 0; i < length; i++) {
            randMunber = random.nextDouble();
            //运算后
            randSetup = uppercase + randMunber * 26;
            //转换成字母
            randCharater = (char) randSetup;
            str += randCharater;
        }
        return str;
    }

    /**
     *
     * 生成大写字母组合随机字符
     * @param length
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterCharToLower(int length) {
        Random random = new Random();
        double randMunber;
        double randSetup;
        char randCharater;
        String str = "";
        for (int i = 0; i < length; i++) {
            randMunber = random.nextDouble();
            //运算后
            randSetup = lowercase + randMunber * 26;
            //转换成字母
            randCharater = (char) randSetup;
            str += randCharater;
        }
        return str;
    }

    /**
     *
     * 生成字母组合随机字符
     * @param length
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterChar(int length) {
        Random random = new Random();
        double randMunber;
        double randSetup;
        char randCharater;
        String str = "";
        for (int i = 0; i < length; i++) {
            randMunber = random.nextDouble();
            // 取得大写字母还是小写字母
            int choice = random.nextInt(2) % 2 == 0 ? uppercase : lowercase;
            //运算后
            randSetup = choice + randMunber * 26;
            //转换成字母
            randCharater = (char) randSetup;
            str += randCharater;
        }
        return str;
    }

    /**
     *
     * 生成数字和字母组合随机数
     * @param length : 生成随机字符的长度
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterCharAndNumUpperAndLower(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            // 字母还是数字
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //字符
            if ("char".equalsIgnoreCase(charOrNum)) {
                // 取得大写字母还是小写字母
                int choice = random.nextInt(2) % 2 == 0 ? uppercase : lowercase;
                //转换成字母
                val += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) {// 数字
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }
    /**
     *
     * 生成数字组合随机数
     * @param length
     * @return
     * @return: 	String
     *
     * Modification History:
     * Date         Author        Version        Discription
     * ----------------------------------------------------------------
     * 2016年1月15日      杨君红                               V1.0           1.0
     * Modify the reason ：修改原因描述
     * Modified to : 修改为
     * @throws
     */
    public static String generaterNum(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            // 字母还是数字
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //字符
            if ("char".equalsIgnoreCase(charOrNum)) {
                i--;
            } else if ("num".equalsIgnoreCase(charOrNum)) {// 数字
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

    public static void main(String[] args) {
        for(int i = 0; i < 256; i++){
            System.out.println((char) i);
            //RandomTool.getStringTimeRandom(5,2);

            //20161117-23234677-1777095
            //20161117182814261PdupBWvz
            //YB20161117182838052MVFiwHci
            //RandomTool.getStringTimeFullRandom(5,8);
            //GetZsdSerialNo();

//            System.out.println("new Random(2).nextInt()" + new Random().nextInt(5));
        }



//        System.out.println("数字  " + RandomTool.generaterNum(6));
//        System.out.println("字符+数字（不区分大小写）  " + RandomTool.generaterCharAndNumUpperAndLower(6));
//        System.out.println("字符（不含有大写元音字母）  " + RandomTool.generaterCharNotContainVowelsToUppercase(6));
//        System.out.println("字符（不含有小写元音字母）  " + RandomTool.generaterCharNotContainVowelsToLower(6));
//        System.out.println("字符（没有限制）  " + RandomTool.generaterChar(6));
//        System.out.println("字符（大写）  " + RandomTool.generaterCharToUppercase(6));
//        System.out.println("字符（小写）  " + RandomTool.generaterCharToLower(6));

    }
}
